package com.dcy.system.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.dcy.common.constant.RedisConstant;
import com.dcy.common.enums.RoleDataScopeEnum;
import com.dcy.system.dao.DeptDao;
import com.dcy.system.dao.ResourceDao;
import com.dcy.system.dao.RoleDao;
import com.dcy.system.dao.UserInfoDao;
import com.dcy.system.model.Role;
import com.dcy.system.model.UserInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author：dcy
 * @Description:
 * @Date: 2021/4/2 15:14
 */
@RequiredArgsConstructor
@Service
public class AuthService {

    private final UserInfoDao userInfoDao;
    private final RoleDao roleDao;
    private final ResourceDao resourceDao;
    private final DeptDao deptDao;


    /**
     * 根据用户id查询权限集合和角色标识
     *
     * @param userId
     * @return
     */
    public List<String> getAuthRoleAndResourceByUserId(String userId) {
        // 查询权限集合
        List<String> resourcesCodeList = getPermissionListByUserId(userId);
        // 查询角色集合
        List<String> roleKeyList = getAuthRoleListByUserId(userId).stream().map(Role::getRoleKey).collect(Collectors.toList());
        CollUtil.addAll(resourcesCodeList, roleKeyList);
        return resourcesCodeList;
    }

    /**
     * 根据用户id查询权限集合
     *
     * @param userId
     * @return
     */
    public List<String> getPermissionListByUserId(String userId) {
        List<String> resourcesCodeList = new ArrayList<>();
        // 查询角色集合
        final List<Role> roles = getAuthRoleListByUserId(userId);
        for (Role role : roles) {
            // 根据角色id查询权限集合
            final List<String> permissionList = resourceDao.selectPermissionListByRoleId(role.getId());
            resourcesCodeList.addAll(permissionList);
        }
        return resourcesCodeList.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 根据用户id查询角色集合
     *
     * @param userId
     * @return
     */
    public List<Role> getAuthRoleListByUserId(String userId) {
        return roleDao.selectRoleListByUserId(userId);
    }

    /**
     * 获取是否拥有所有数据权限
     *
     * @param userId 用户id
     * @return true：拥有所有的数据权限；false：未拥有
     */
    public Boolean getAllDataScopeFlag(String userId) {
        // 是否有全部数据权限
        return getAuthRoleListByUserId(userId).stream()
                .anyMatch(role -> RoleDataScopeEnum.ALL.getCode().equals(role.getDataScope()));
    }

    /**
     * 根据角色id获取权限集合
     *
     * @param userId
     * @return
     */
    public Set<String> getDataScopeListByUserId(final String userId) {
        Set<String> authDeptIds = new HashSet<>();
        getAuthRoleListByUserId(userId).forEach(role -> {
            // 获取枚举值
            final RoleDataScopeEnum dataScope = RoleDataScopeEnum.getByCode(role.getDataScope());
            if (dataScope != null) {
                switch (dataScope) {
                    case CUSTOM:
                        // 获取能看到的部门ids
                        final List<String> seeDeptIds = roleDao.selectAuthDeptIdsByRoleId(role.getId());
                        if (CollUtil.isNotEmpty(seeDeptIds)) {
                            authDeptIds.addAll(seeDeptIds);
                        }
                        break;
                    case ME_DEPT:
                        // 获取用户信息
                        UserInfo userInfo = userInfoDao.getById(userId);
                        authDeptIds.add(userInfo.getDeptId());
                        break;
                    case ME_DEPT_CHILD:
                        UserInfo userInfoOne = userInfoDao.getById(userId);
                        if (StrUtil.isNotBlank(userInfoOne.getDeptId())) {
                            authDeptIds.add(userInfoOne.getDeptId());
                            // 查询所有的子级
                            final List<String> childrenIds = deptDao.selectChildrenById(userInfoOne.getDeptId());
                            if (CollUtil.isNotEmpty(childrenIds)) {
                                authDeptIds.addAll(childrenIds);
                            }
                        }
                        break;
                    default:
                }
            }
        });
        return authDeptIds;
    }
}
